package utils

import (
	"time"
	"net/http"
	"math/rand"
    "strings"
    
    "github.com/astaxie/beego"
    jwt "github.com/dgrijalva/jwt-go"
)

const (
    MySecret = "zFG5uCQvW6IjoiTLJBeUoK5H4nPz5d2hA7ng5bGKzV4="
)

func CheckCookieEffective(username, cookies string, ValueEmail map[string]string) bool {
	if username == ValueEmail[cookies] {
		return true
	}
	return false
}

type MarCookies struct {
	Cookies *http.Cookie
}
// var MarCookies map[string]http.Cookie

func (this *MarCookies) NewMarCookies(username string){
	this.Cookies = &http.Cookie{
		Name: "key",
		Value: username + ":" + GenRandomCharactars256(),
		// Expires: time.Now().Add(60*time.Second), //
		MaxAge: 60,
		HttpOnly: true,
    }
    beego.Info(this.Cookies.Value)
}

func (this *MarCookies) NewJWTTokenCookies(username string){
	// Create a new token object, specifying signing method and the claims
	// you would like it to contain.
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"user": username,
		"exp": time.Now().Add(24*time.Hour).Unix(),
	})

	// Sign and get the complete encoded token as a string using the secret
	tokenString, _ := token.SignedString([]byte(MySecret))
    beego.Info(tokenString)

    this.ParseJWTToken(tokenString)
	this.Cookies = &http.Cookie{
		Name: "key",
		Value: tokenString,
		// Expires: time.Now().Add(60*time.Second),
		MaxAge: 60,
		HttpOnly: true,
	}
}

type MyCustomClaims struct {
    User string `json:"user"`
    Mobile string `json:"mob,omitempty"`
    jwt.StandardClaims
}

func (this *MarCookies) ParseJWTToken(tokenString string) string {
    token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
        return []byte(MySecret), nil
    })
    if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
        beego.Info("expireAT",claims.StandardClaims.ExpiresAt)
        beego.Info("user is:", claims.User, "Expire At: ", claims.StandardClaims.ExpiresAt)
        return claims.User
    } else {
        beego.Error(err)
        return ""
    }
}

func (this *MarCookies) IsJWTEffect(tokenString string) bool {
    token, _ := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
        return []byte(MySecret), nil
    })
    return token.Valid
}

func GetCookieValue(cookiestr string) string {
    if cookiestr != "" {
        z := strings.Split(cookiestr, ":")
        return z[1]
    } else {
        return ""
    }
}

// Check if the user is logged in, true if they do
func IsLoggedIn(cookiestring string, ValueMobile map[string]string) bool {
    var mobile, value string
    if cookiestring != "" {
        z := strings.Split(cookiestring, ":")
	    mobile = z[0]
	    value = z[1]
    } else {
        return false
    }    
	// 根据key找到username， 判断是否是正确的用户
	expectedMobile := ValueMobile[value]
    // If SessionID matches the expected SessionID, it is Good
	if mobile == expectedMobile {
        // If you want to be really secure check IP
	    return true
	}
	return false
}

// 自动清除无效的cookie
func (this *MarCookies)MarDeleteCookie(){

}

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

func GenRandomCharactars256() string {
    b := make([]byte, 256)
    for i := range b {
        b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	beego.Info(string(b))
    return string(b)
}

func GenRandomCharactarsLenN(n int) string {
    b := make([]byte, n)
    for i := range b {
        b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	beego.Info(string(b))
    return string(b)
}
